<?php
namespace Kcdns\Service\User;

class Account extends \Think\Model
{

    static $instace;

    protected $name = 'user_account';

    public static function getInstance ()
    {
        return self::$instace ?  : (self::$instace = new self());
    }
    
    // 获取用户可用账户列表
    public function getUserAllAccount ($userId)
    {
        $accounts = $this->field('a.*,b.title as card_title')->where(array(
                'a.uid' => $userId,
                'a.status' => 1
        ))->join("a LEFT JOIN __USER_CARD__ b ON a.card_id=b.id")->order('type asc')->select() ?  : array();
        $type1Found = false;
        foreach ($accounts as $k => $v)
        {
            if ($v['type'] == 1)
            {
                $type1Found = true;
            }
            $accounts[$k] = array(
                    'id' => $v['id'],
                    'no' => $v['no'],
                    'type' => $v['type'],
                    'suid' => $v['suid'],
                    'building_id' => $v['building_id'],
                    'card_id' => $v['card_id'],
                    'card_title' => $v['card_title'],
                    'amount' => $v['amount']
            );
        }
        if (! $type1Found)
        {
            array_unshift($accounts, array(
                    'id' => - 1,
                    'type' => 1,
                    'amount' => 0
            ));
        }
        return $accounts;
    }
    
    // 充值
    public function recharge ($type, $orderRecord,$refData)
    {
        filter($type, 'required;enum=1,2,3;');
        $account = $this->_getOrCreateAccount($orderRecord['uid'], $orderRecord['suid'], $orderRecord['building_id'], $type);
        $arr = [1=>'账户充值(在线支付)', 2=>'会员卡充值(在线支付)',3=>'会议室会员卡充值(在线支付)'];
        $title = $arr[$type];
        $cardId = $refData['card_id'];
        $buildingId = $refData['building_id'];

        // 更新会员卡
        if (($type == 2 || $type == 3) && $cardId)
        {
            M('user_account')->where(array(
                'id' => $account['id']
            ))->data(array(
                'card_id' => $cardId
            ))->save();
        }
        return $this->_change($account, $orderRecord, $title, 1);
    }
    
    // 激活码充值
    public function rechargeWithCode ($userId, $code)
    {
        OE('util')->validate($code, 'pattern=/^[0-9A-Za-z]+$/');
        
        // 激活码记录
        $codeRecord = M('user_code')->where(array(
            'code' => $code,
            'status' => 1,
            'is_delete' => 0
        ))->find();
        if (! $codeRecord)
        {
            throw new \Exception("激活码无效");
        }
        
        // 更新激活码
        $codeData = array(
                'uid' => $userId,
                'active_time' => date('Y-m-d H:i:s'),
                'status' => 2
        );
        M('user_code')->data($codeData)->where(array(
                'code' => $code
        ))->save();
        
        $type = $codeRecord['type'] ?  : 1;
        $account = $this->_getOrCreateAccount($userId, $codeRecord['suid'], null, $type);
        $title = $type == 1 ? '账户充值(激活码)' : '会员卡充值(激活码)';
        $orderRecord = array(
                'no' => $code,
                'uid' => $userId,
                'suid' => $codeRecord['suid'],
                'amount' => $codeRecord['amount']
        );
        return $this->_change($account, $orderRecord, $title, 1);
    }

    // 红包充值
    public function rechargeHongbao($userId, $money)
    {
        $account = $this->_getOrCreateAccount($userId, null, null, 1);

        $title = '开锁赠送红包';
        $orderRecord = [
            'uid' => $userId,
            'amount' => $money
        ];
        return $this->_change($account, $orderRecord, $title, 1);
    }

    // 余额支付
    public function pay ($userId, $accountId, $orderRecord = array())
    {
        OE('util')->validate($orderRecord['amount'], 'required;price');

        $user = User::getInstance()->get($userId);

        // 检查账户
        $account = $this->where(array(
            'uid' => $userId,
            'id' => $accountId,
            'status' => 1
        ))->find();
        if (! $account)
        {
            throw new \Exception('账户无效');
        }

        if ($orderRecord['amount'] > $account['amount'])
        {
            throw new \Exception('账户余额不足');
        }

        switch ($orderRecord['type'])
        {
            case '1':
                $title = '购买了' . $orderRecord['title'] . '的商品';
                break;
            case '3':
            case '4':
                $title = '预定了' . $orderRecord['title'];
                break;
            default:
                $title = '消费';
        }

        // 红包处理  红包不可拆分  优先使用大额的  最先领取的
        $money    = 0;
        $hongbaoList = M('Hongbao')->where(['uid'=>$userId, 'status' => ['lt', 2]])->order('money desc,id asc')->select();
        if (!empty($hongbaoList)) {
            foreach ($hongbaoList as $k => $v) {
                if (($money+$v['money']) <= $orderRecord['amount']) {
                    $money += $v['money'];
                    M('Hongbao')->where(['id' => $v['id']])->save([
                        'order_no' => $orderRecord['no'],
                        'status' => 2
                    ]);

                    if($money==$orderRecord['amount']){
                        break;
                    }
                }
            }
        }
        $this->_change($account, $orderRecord, $title, 2);

        return $payRecord = array(
            'order_no' => $orderRecord['no'],
            'pay_type' => $account['type'] == 2 ? 'card' : 'account',
            'pay_id' => $account['id'],
            'amount' => $orderRecord['amount']
        );
    }

    // 零元余额支付
    public function payZero ($userId, $orderRecord = array())
    {
        OE('util')->validate($orderRecord['amount'], 'required;price');

        // 检查账户
        $account = $this->where([ 'uid' => $userId, 'type' => 1, 'status' => 1])->find();
        if (!$account)
        {
            $account = $this->_getOrCreateAccount($userId, '', '', 1);
            // throw new \Exception('账户无效');
        }

        switch ($orderRecord['type'])
        {
            case '1':
                $title = '购买了' . $orderRecord['title'] . '的商品';
                break;
            case '3':
            case '4':
                $title = '预定了' . $orderRecord['title'];
                break;
            default:
                $title = '消费';
        }

        $this->_change($account, $orderRecord, $title, 2);

        return $payRecord = array(
            'order_no' => $orderRecord['no'],
            'pay_type' => 'zero',
            'pay_id' => $account['id'],
            'amount' => $orderRecord['amount']
        );
    }

    /**
     * @param $userId
     * @param $shopUserId
     * @param $orderRecord
     * @param $refundMoney
     * 账户余额退款
     */
    public function refund ($userId,$shopUserId,$orderRecord,$refundMoney)
    {
        // 检查账户
        $where = array(
            'uid' => $userId,
            'status' => 1,
            'type'=>$orderRecord['pay_type']=='card'?2:'1',
        );
        $orderRecord['pay_type'] == 'account' ? '' : $where['suid'] = $shopUserId;
        $account = $this->where($where)->find();
        if (! $account)
        {
            throw new \Exception('账户无效');
        }

        $orderRecord['amount']=$refundMoney;

        //退款账户变动
        $this->_change($account, $orderRecord, '订单退款('.$orderRecord['no'].')',3);

        return $payRecord = array(
            'order_no' => $orderRecord['no'],
            'pay_type' => $orderRecord['pay_type'],
            'pay_id' => $account['id'],
            'amount' => $orderRecord['amount']
        );

    }
    
    // 账户明细
    public function getLog ($userId, $accountId, $pageNo = 1, $pageSize = 20)
    {
        $where = array(
                'uid' => $userId,
                // 'account_id' => $accountId
        );
        $count = M('user_account_log')->where($where)->count();
        $list = M('user_account_log')->where($where)->order('id desc')->limit(($pageNo - 1) * $pageSize, $pageSize)->select();
        return array(
                'count' => $count,
                'list' => $list
        );
    }
    
    // 获取/创建 账户
    protected function _getOrCreateAccount ($uid, $suid, $buildingId, $type)
    {
        if ($suid)
        {
            $where = array(
                    'uid' => $uid,
                    'type' => $type
            );
        }
        elseif ($buildingId)
        {
            $where = array(
                    'uid' => $uid,
                    'type' => $type
            );
        }
        
        if ($type == 2)
        {
            if ($suid)
            {
                $where['suid'] = filter($suid, 'int');
            }
            elseif ($buildingId)
            {
                $where['building_id'] = filter($buildingId, 'int');
            }
            else
            {
                throw new \Exception('error');
            }
        } elseif ($type == 3 && $buildingId)
        {
            $where['building_id'] = filter($buildingId, 'int');
        }

        if (empty($where)) {
            $where = [
                'uid' => $uid,
                'type' => 1
            ];
        }
        
        $record = $this->where($where)->find();
        if (! $record)
        {
            $data = $where;
            $data['no'] = $this->_genNo($uid, $suid, $type);
            $data['amount'] = 0.00;
            $data['create_time'] = date('Y-m-d H:i:s');
            $data['status'] = 1;
            $this->data($data)->add();
            $record = $this->where($where)->find();
        }
        if (! $record)
        {
            throw new \Exception('创建账户失败');
        }
        return $record;
    }

    protected function _genNo ($uid, $suid, $type)
    {
        $no = OE('util')->rand(12, 1, $type);
        if ($this->where(array(
                "no" => $no
        ))->find())
        {
            return $this->_genNo($uid, $suid, $type);
        }
        return $no;
    }
    
    // $orderRecord = ['uid'=>123,'suid'=>'123','amount'=>100.00,'no'=>'1231231123','pay_id'=>'123123'];
    protected function _change ($account, $orderRecord, $title, $type)
    {
        if ($account['uid'] !== $orderRecord['uid'])
        {
            throw new \Exception('账户和订单不匹配');
        }
        
        if ($account['type'] == 2 and $account['suid'] and $account['suid'] !== $orderRecord['suid'])
        {
            throw new \Exception('账户和订单不匹配');
        }
        
        $amount = $type == 1 || $type == 3 ? $account['amount'] + $orderRecord['amount'] : $account['amount'] - $orderRecord['amount'];
        
        // 更新账户
        if ($this->data(array(
                'amount' => $amount,
                'update_time' => date('Y-m-d H:i:s')
        ))->where(array(
                'id' => $account['id']
        ))->save() === false)
        {
            throw new \Exception("账户充值失败");
        }
        
        // 记录账户变动日志
        $logData = array(
                'uid' => $account['uid'],
                'suid' => $account['suid'],
                'account_id' => $account['id'],
                'type' => $type, // 1:充值; 2:消费; 3:退款;
                'amount' => $orderRecord['amount'],
                'pre_amount' => $account['amount'],
                'create_time' => date('Y-m-d H:i:s'),
                'order_id' => $orderRecord['no'],
                'pay_id' => $orderRecord['pay_id'],
                'title' => $title,
                'order_type' => $orderRecord['type'],
                'order_stype' => $orderRecord['stype']
        );
        
        M('user_account_log')->data($logData)->add();
        
        return true;
    }
}